"""
交易决策分析模块
提供买卖时机、仓位管理、价格关键位分析
支持短线、中线、长线投资策略
"""

import pandas as pd
import numpy as np
import logging
from typing import Dict, List, Tuple


class TradingAdvisor:
    """交易决策分析器"""
    
    def __init__(self, realtime_data: Dict, hist_data: pd.DataFrame):
        """
        初始化
        
        参数:
            realtime_data: 实时数据
            hist_data: 历史数据（含技术指标）
        """
        self.realtime_data = realtime_data
        self.hist_data = hist_data
        self.current_price = realtime_data.get('最新价', 0) if realtime_data else hist_data.iloc[-1]['收盘']
        
    def analyze_support_resistance(self) -> Dict:
        """
        分析支撑位和压力位
        
        返回:
            Dict: 包含支撑位、压力位、突破位等信息
        """
        try:
            df = self.hist_data.tail(60)  # 使用最近60天数据
            
            # 1. 基于历史高低点
            recent_high = df['最高'].max()
            recent_low = df['最低'].min()
            
            # 2. 基于均线
            ma5 = df['MA5'].iloc[-1] if 'MA5' in df.columns else None
            ma10 = df['MA10'].iloc[-1] if 'MA10' in df.columns else None
            ma20 = df['MA20'].iloc[-1] if 'MA20' in df.columns else None
            ma60 = df['MA60'].iloc[-1] if 'MA60' in df.columns else None
            
            # 3. 基于布林带
            boll_upper = df['BOLL_UPPER'].iloc[-1] if 'BOLL_UPPER' in df.columns else None
            boll_mid = df['BOLL_MID'].iloc[-1] if 'BOLL_MID' in df.columns else None
            boll_lower = df['BOLL_LOWER'].iloc[-1] if 'BOLL_LOWER' in df.columns else None
            
            # 4. 寻找关键支撑位（按强度排序）
            support_levels = []
            if pd.notna(boll_lower):
                support_levels.append(('布林下轨', boll_lower, '强'))
            if pd.notna(ma20):
                support_levels.append(('MA20', ma20, '强'))
            if pd.notna(ma60):
                support_levels.append(('MA60', ma60, '中'))
            
            # 添加历史低点作为支撑
            support_levels.append(('近期低点', recent_low, '强'))
            
            # 计算斐波那契回调位（技术分析常用）
            fib_382 = recent_low + (recent_high - recent_low) * 0.382
            fib_500 = recent_low + (recent_high - recent_low) * 0.500
            fib_618 = recent_low + (recent_high - recent_low) * 0.618
            
            support_levels.append(('斐波那契38.2%', fib_382, '中'))
            support_levels.append(('斐波那契50.0%', fib_500, '中'))
            
            # 5. 寻找关键压力位（按强度排序）
            resistance_levels = []
            if pd.notna(boll_upper):
                resistance_levels.append(('布林上轨', boll_upper, '强'))
            if pd.notna(ma60):
                resistance_levels.append(('MA60', ma60, '中'))
            if pd.notna(ma20):
                resistance_levels.append(('MA20', ma20, '强'))
            
            # 添加历史高点作为压力
            resistance_levels.append(('近期高点', recent_high, '强'))
            resistance_levels.append(('斐波那契61.8%', fib_618, '中'))
            
            # 过滤：支撑位应该低于当前价，压力位应该高于当前价
            valid_supports = [(name, price, strength) for name, price, strength in support_levels 
                             if price < self.current_price]
            valid_resistances = [(name, price, strength) for name, price, strength in resistance_levels 
                                if price > self.current_price]
            
            # 排序：支撑位从高到低（离当前价最近的最重要），压力位从低到高
            valid_supports.sort(key=lambda x: x[1], reverse=True)
            valid_resistances.sort(key=lambda x: x[1])
            
            # 取前3个最重要的
            top_supports = valid_supports[:3]
            top_resistances = valid_resistances[:3]
            
            # 6. 判断突破位
            breakthrough_signal = self._analyze_breakthrough(df)
            
            return {
                'current_price': self.current_price,
                'support_levels': top_supports,
                'resistance_levels': top_resistances,
                'recent_high': recent_high,
                'recent_low': recent_low,
                'price_range': recent_high - recent_low,
                'position_in_range': (self.current_price - recent_low) / (recent_high - recent_low) if recent_high > recent_low else 0.5,
                'breakthrough_signal': breakthrough_signal,
                'fibonacci': {
                    '38.2%': fib_382,
                    '50.0%': fib_500,
                    '61.8%': fib_618
                }
            }
            
        except Exception as e:
            logging.error(f"分析支撑压力位时出错: {e}")
            return {}
    
    def _analyze_breakthrough(self, df: pd.DataFrame) -> Dict:
        """
        分析突破信号
        
        返回:
            Dict: 突破信号分析
        """
        try:
            latest = df.iloc[-1]
            prev = df.iloc[-2] if len(df) > 1 else latest
            
            signals = []
            
            # 1. 突破布林上轨（可能超买）
            if 'BOLL_UPPER' in df.columns:
                if latest['收盘'] > latest['BOLL_UPPER'] and prev['收盘'] <= prev['BOLL_UPPER']:
                    signals.append({
                        'type': '向上突破',
                        'level': '布林上轨',
                        'price': latest['BOLL_UPPER'],
                        'strength': '强',
                        'meaning': '短期超买，注意回调风险'
                    })
            
            # 2. 跌破布林下轨（可能超卖）
            if 'BOLL_LOWER' in df.columns:
                if latest['收盘'] < latest['BOLL_LOWER'] and prev['收盘'] >= prev['BOLL_LOWER']:
                    signals.append({
                        'type': '向下突破',
                        'level': '布林下轨',
                        'price': latest['BOLL_LOWER'],
                        'strength': '强',
                        'meaning': '短期超卖，可能反弹'
                    })
            
            # 3. 突破MA20（中期趋势）
            if 'MA20' in df.columns:
                if latest['收盘'] > latest['MA20'] and prev['收盘'] <= prev['MA20']:
                    signals.append({
                        'type': '向上突破',
                        'level': 'MA20',
                        'price': latest['MA20'],
                        'strength': '中',
                        'meaning': '中期趋势转好'
                    })
                elif latest['收盘'] < latest['MA20'] and prev['收盘'] >= prev['MA20']:
                    signals.append({
                        'type': '向下突破',
                        'level': 'MA20',
                        'price': latest['MA20'],
                        'strength': '中',
                        'meaning': '中期趋势转弱'
                    })
            
            # 4. 突破近期高点（强势信号）
            recent_high = df['最高'].iloc[-10:].max()
            if latest['最高'] > recent_high:
                signals.append({
                    'type': '向上突破',
                    'level': '近期高点',
                    'price': recent_high,
                    'strength': '强',
                    'meaning': '强势突破，可能继续上涨'
                })
            
            # 5. 跌破近期低点（弱势信号）
            recent_low = df['最低'].iloc[-10:].min()
            if latest['最低'] < recent_low:
                signals.append({
                    'type': '向下突破',
                    'level': '近期低点',
                    'price': recent_low,
                    'strength': '强',
                    'meaning': '弱势下跌，注意止损'
                })
            
            return {
                'has_breakthrough': len(signals) > 0,
                'signals': signals,
                'signal_count': len(signals)
            }
            
        except Exception as e:
            logging.error(f"分析突破信号时出错: {e}")
            return {'has_breakthrough': False, 'signals': [], 'signal_count': 0}
    
    def position_management_advice(self) -> Dict:
        """
        仓位管理建议
        
        返回:
            Dict: 加仓、减仓、持仓建议
        """
        try:
            df = self.hist_data.tail(30)
            latest = df.iloc[-1]
            
            # 获取技术指标
            rsi = latest.get('RSI6', 50)
            kdj_k = latest.get('K', 50)
            macd = latest.get('MACD', 0)
            
            # 获取价格位置
            price_analysis = self.analyze_support_resistance()
            position_in_range = price_analysis.get('position_in_range', 0.5)
            
            # 评分系统（0-100）
            buy_score = 0
            sell_score = 0
            
            # 1. RSI评分
            if rsi < 30:
                buy_score += 30  # 超卖，强烈买入信号
            elif rsi < 40:
                buy_score += 20  # 偏低，买入信号
            elif rsi > 70:
                sell_score += 30  # 超买，强烈卖出信号
            elif rsi > 60:
                sell_score += 20  # 偏高，卖出信号
            
            # 2. KDJ评分
            if kdj_k < 20:
                buy_score += 25  # 超卖
            elif kdj_k < 40:
                buy_score += 15
            elif kdj_k > 80:
                sell_score += 25  # 超买
            elif kdj_k > 60:
                sell_score += 15
            
            # 3. MACD评分
            if macd > 0:
                buy_score += 20  # 多头
            else:
                sell_score += 20  # 空头
            
            # 4. 价格位置评分
            if position_in_range < 0.3:
                buy_score += 25  # 接近低位
            elif position_in_range < 0.5:
                buy_score += 15
            elif position_in_range > 0.7:
                sell_score += 25  # 接近高位
            elif position_in_range > 0.5:
                sell_score += 15
            
            # 5. 均线排列评分
            ma5 = latest.get('MA5')
            ma10 = latest.get('MA10')
            ma20 = latest.get('MA20')
            
            if pd.notna(ma5) and pd.notna(ma10) and pd.notna(ma20):
                if ma5 > ma10 > ma20:
                    buy_score += 20  # 多头排列
                elif ma5 < ma10 < ma20:
                    sell_score += 20  # 空头排列
            
            # 决策逻辑
            total_score = buy_score - sell_score
            
            if total_score > 60:
                action = '强烈建议加仓'
                position_change = '+30%~+50%'
                reason = '多项指标显示强烈买入信号'
                risk_level = '中'
            elif total_score > 30:
                action = '适当加仓'
                position_change = '+10%~+30%'
                reason = '技术指标偏多，可适当增加仓位'
                risk_level = '中低'
            elif total_score > -30:
                action = '持仓观望'
                position_change = '0%'
                reason = '多空信号均衡，暂时持有'
                risk_level = '低'
            elif total_score > -60:
                action = '适当减仓'
                position_change = '-10%~-30%'
                reason = '技术指标偏空，建议减少仓位'
                risk_level = '中'
            else:
                action = '强烈建议减仓'
                position_change = '-30%~-50%'
                reason = '多项指标显示强烈卖出信号'
                risk_level = '高'
            
            return {
                'action': action,
                'position_change': position_change,
                'reason': reason,
                'buy_score': buy_score,
                'sell_score': sell_score,
                'total_score': total_score,
                'risk_level': risk_level,
                'details': {
                    'RSI': f'{rsi:.2f} ({"超卖" if rsi < 30 else "超买" if rsi > 70 else "正常"})',
                    'KDJ_K': f'{kdj_k:.2f} ({"超卖" if kdj_k < 20 else "超买" if kdj_k > 80 else "正常"})',
                    'MACD': f'{macd:.2f} ({"多头" if macd > 0 else "空头"})',
                    '价格位置': f'{position_in_range*100:.1f}% ({"低位" if position_in_range < 0.3 else "高位" if position_in_range > 0.7 else "中位"})'
                }
            }
            
        except Exception as e:
            logging.error(f"生成仓位管理建议时出错: {e}")
            return {
                'action': '持仓观望',
                'position_change': '0%',
                'reason': '数据不足，建议观望',
                'risk_level': '未知'
            }
    
    def calculate_entry_price(self) -> Dict:
        """
        计算合理买入价格区间
        
        返回:
            Dict: 买入价格建议
        """
        try:
            price_analysis = self.analyze_support_resistance()
            
            # 获取关键支撑位
            supports = price_analysis.get('support_levels', [])
            
            if len(supports) == 0:
                # 没有明确支撑位，使用当前价下方3%、5%、8%
                return {
                    'aggressive_entry': round(self.current_price * 0.97, 2),  # 激进：-3%
                    'moderate_entry': round(self.current_price * 0.95, 2),    # 稳健：-5%
                    'conservative_entry': round(self.current_price * 0.92, 2),  # 保守：-8%
                    'stop_loss': round(self.current_price * 0.90, 2),         # 止损：-10%
                    'current_price': self.current_price,
                    'strategy': '无明确支撑位，建议回调后买入'
                }
            
            # 有明确支撑位，使用支撑位作为参考
            strongest_support = supports[0][1]  # 最强支撑位
            
            # 买入价格策略
            aggressive = round(self.current_price * 0.98, 2)  # 激进：接近当前价
            moderate = round((self.current_price + strongest_support) / 2, 2)  # 稳健：中间价
            conservative = round(strongest_support * 1.02, 2)  # 保守：支撑位上方2%
            stop_loss = round(strongest_support * 0.95, 2)  # 止损：支撑位下方5%
            
            return {
                'aggressive_entry': aggressive,
                'moderate_entry': moderate,
                'conservative_entry': conservative,
                'stop_loss': stop_loss,
                'current_price': self.current_price,
                'strongest_support': strongest_support,
                'support_name': supports[0][0],
                'strategy': f'建议在{supports[0][0]}({strongest_support:.2f})附近分批买入'
            }
            
        except Exception as e:
            logging.error(f"计算买入价格时出错: {e}")
            return {
                'current_price': self.current_price,
                'strategy': '数据不足，建议谨慎操作'
            }
    
    def multi_timeframe_strategy(self) -> Dict:
        """
        多周期投资策略（短线、中线、长线）
        
        返回:
            Dict: 不同周期的投资建议
        """
        try:
            df = self.hist_data
            latest = df.iloc[-1]
            
            # ===== 短线策略（1-5天）=====
            short_term = self._short_term_strategy(df)
            
            # ===== 中线策略（5-30天）=====
            mid_term = self._mid_term_strategy(df)
            
            # ===== 长线策略（30天以上）=====
            long_term = self._long_term_strategy(df)
            
            # ===== 综合建议 =====
            recommendations = {
                '短线': short_term,
                '中线': mid_term,
                '长线': long_term
            }
            
            # 计算综合评分
            short_score = short_term.get('score', 50)
            mid_score = mid_term.get('score', 50)
            long_score = long_term.get('score', 50)
            
            overall_score = (short_score * 0.2 + mid_score * 0.3 + long_score * 0.5)
            
            if overall_score >= 70:
                overall_rating = '非常看好'
            elif overall_score >= 60:
                overall_rating = '看好'
            elif overall_score >= 50:
                overall_rating = '中性'
            elif overall_score >= 40:
                overall_rating = '看淡'
            else:
                overall_rating = '非常看淡'
            
            return {
                'recommendations': recommendations,
                'overall_score': round(overall_score, 2),
                'overall_rating': overall_rating
            }
            
        except Exception as e:
            logging.error(f"生成多周期策略时出错: {e}")
            return {}
    
    def _short_term_strategy(self, df: pd.DataFrame) -> Dict:
        """短线策略（1-5天）"""
        try:
            recent = df.tail(10)
            latest = recent.iloc[-1]
            
            score = 50  # 基础分50
            signals = []
            
            # 1. RSI指标（快速反应）
            rsi = latest.get('RSI6', 50)
            if rsi < 30:
                score += 20
                signals.append('RSI超卖，短期反弹可能')
            elif rsi > 70:
                score -= 20
                signals.append('RSI超买，注意短期回调')
            
            # 2. KDJ指标（短线首选）
            kdj_k = latest.get('K', 50)
            kdj_d = latest.get('D', 50)
            if kdj_k < 20:
                score += 20
                signals.append('KDJ超卖区，短线买入时机')
            elif kdj_k > 80:
                score -= 20
                signals.append('KDJ超买区，短线卖出时机')
            
            # 3. 5日均线
            ma5 = latest.get('MA5')
            if pd.notna(ma5) and self.current_price > ma5:
                score += 10
                signals.append('站上5日线，短期趋势向好')
            elif pd.notna(ma5) and self.current_price < ma5:
                score -= 10
                signals.append('跌破5日线，短期趋势转弱')
            
            # 4. 成交量
            vol_ma5 = latest.get('VOL_MA5')
            current_vol = latest.get('成交量')
            if pd.notna(vol_ma5) and pd.notna(current_vol) and current_vol > vol_ma5 * 1.5:
                score += 10
                signals.append('放量上涨，短线活跃')
            
            # 操作建议
            if score >= 70:
                action = '积极买入'
                risk = '中'
            elif score >= 60:
                action = '可以买入'
                risk = '中低'
            elif score >= 40:
                action = '观望为主'
                risk = '低'
            else:
                action = '建议回避'
                risk = '高'
            
            return {
                'period': '短线（1-5天）',
                'score': score,
                'action': action,
                'risk': risk,
                'signals': signals,
                'focus': 'RSI、KDJ、5日线',
                'profit_target': '3-5%',
                'stop_loss': '2-3%'
            }
            
        except Exception as e:
            logging.error(f"短线策略分析出错: {e}")
            return {'period': '短线', 'score': 50, 'action': '观望'}
    
    def _mid_term_strategy(self, df: pd.DataFrame) -> Dict:
        """中线策略（5-30天）"""
        try:
            recent = df.tail(30)
            latest = recent.iloc[-1]
            
            score = 50
            signals = []
            
            # 1. 20日均线（中线核心）
            ma20 = latest.get('MA20')
            if pd.notna(ma20) and self.current_price > ma20:
                score += 20
                signals.append('站上20日线，中期趋势向好')
            elif pd.notna(ma20) and self.current_price < ma20:
                score -= 20
                signals.append('跌破20日线，中期趋势转弱')
            
            # 2. MACD指标
            macd = latest.get('MACD', 0)
            dif = latest.get('DIF', 0)
            dea = latest.get('DEA', 0)
            
            if macd > 0 and dif > dea:
                score += 15
                signals.append('MACD金叉，中期看多')
            elif macd < 0 and dif < dea:
                score -= 15
                signals.append('MACD死叉，中期看空')
            
            # 3. 均线排列
            ma5 = latest.get('MA5')
            ma10 = latest.get('MA10')
            if pd.notna(ma5) and pd.notna(ma10) and pd.notna(ma20):
                if ma5 > ma10 > ma20:
                    score += 15
                    signals.append('多头排列，中期强势')
                elif ma5 < ma10 < ma20:
                    score -= 15
                    signals.append('空头排列，中期弱势')
            
            # 4. RSI（中期）
            rsi = latest.get('RSI12', 50)
            if 40 <= rsi <= 60:
                score += 10
                signals.append('RSI中性区域，波动可控')
            
            # 操作建议
            if score >= 70:
                action = '建议持有/加仓'
                risk = '中低'
            elif score >= 60:
                action = '可以持有'
                risk = '中'
            elif score >= 40:
                action = '减仓观望'
                risk = '中'
            else:
                action = '建议离场'
                risk = '中高'
            
            return {
                'period': '中线（5-30天）',
                'score': score,
                'action': action,
                'risk': risk,
                'signals': signals,
                'focus': 'MA20、MACD、均线排列',
                'profit_target': '10-20%',
                'stop_loss': '5-8%'
            }
            
        except Exception as e:
            logging.error(f"中线策略分析出错: {e}")
            return {'period': '中线', 'score': 50, 'action': '观望'}
    
    def _long_term_strategy(self, df: pd.DataFrame) -> Dict:
        """长线策略（30天以上）"""
        try:
            score = 50
            signals = []
            latest = df.iloc[-1]
            
            # 1. 60日均线（长期趋势）
            ma60 = latest.get('MA60')
            if pd.notna(ma60) and self.current_price > ma60:
                score += 25
                signals.append('站上60日线，长期趋势向好')
            elif pd.notna(ma60) and self.current_price < ma60:
                score -= 25
                signals.append('跌破60日线，长期趋势转弱')
            
            # 2. 长期均线排列
            ma20 = latest.get('MA20')
            ma60 = latest.get('MA60')
            if pd.notna(ma20) and pd.notna(ma60):
                if ma20 > ma60:
                    score += 15
                    signals.append('中长期均线多头，长期看好')
                else:
                    score -= 15
                    signals.append('中长期均线空头，长期谨慎')
            
            # 3. 价格相对位置（长期视角）
            recent_120 = df.tail(120) if len(df) >= 120 else df
            price_high = recent_120['最高'].max()
            price_low = recent_120['最低'].min()
            
            if price_high > price_low:
                position = (self.current_price - price_low) / (price_high - price_low)
                if position < 0.3:
                    score += 20
                    signals.append('价格处于长期低位，投资价值显现')
                elif position > 0.7:
                    score -= 20
                    signals.append('价格处于长期高位，注意估值风险')
            
            # 4. 趋势强度（ADX）
            if 'ADX' in latest:
                adx = latest['ADX']
                if pd.notna(adx) and adx > 25:
                    score += 10
                    signals.append('趋势明确，适合趋势跟随')
            
            # 5. 基本面因素（如果有数据）
            if self.realtime_data:
                pe = self.realtime_data.get('市盈率')
                if pe and pe < 20:
                    score += 10
                    signals.append('市盈率较低，估值合理')
                elif pe and pe > 50:
                    score -= 10
                    signals.append('市盈率较高，估值偏贵')
            
            # 操作建议
            if score >= 70:
                action = '长期持有/定投'
                risk = '低'
            elif score >= 60:
                action = '适合长期持有'
                risk = '中低'
            elif score >= 40:
                action = '谨慎持有'
                risk = '中'
            else:
                action = '不建议长期持有'
                risk = '中高'
            
            return {
                'period': '长线（30天以上）',
                'score': score,
                'action': action,
                'risk': risk,
                'signals': signals,
                'focus': 'MA60、趋势、估值',
                'profit_target': '30%+',
                'stop_loss': '15-20%'
            }
            
        except Exception as e:
            logging.error(f"长线策略分析出错: {e}")
            return {'period': '长线', 'score': 50, 'action': '观望'}
    
    def comprehensive_trading_plan(self) -> Dict:
        """
        综合交易计划
        整合所有分析结果，给出完整的交易建议
        
        返回:
            Dict: 完整的交易计划
        """
        try:
            # 1. 价格关键位分析
            price_levels = self.analyze_support_resistance()
            
            # 2. 仓位管理建议
            position_advice = self.position_management_advice()
            
            # 3. 买入价格建议
            entry_price = self.calculate_entry_price()
            
            # 4. 多周期策略
            multi_strategy = self.multi_timeframe_strategy()
            
            # 5. 风险收益比计算
            risk_reward = self._calculate_risk_reward(price_levels, entry_price)
            
            return {
                'price_levels': price_levels,
                'position_advice': position_advice,
                'entry_price': entry_price,
                'multi_strategy': multi_strategy,
                'risk_reward': risk_reward,
                'generated_at': pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')
            }
            
        except Exception as e:
            logging.error(f"生成综合交易计划时出错: {e}")
            return {}
    
    def _calculate_risk_reward(self, price_levels: Dict, entry_price: Dict) -> Dict:
        """
        计算风险收益比
        
        返回:
            Dict: 风险收益比分析
        """
        try:
            current = self.current_price
            stop_loss = entry_price.get('stop_loss', current * 0.9)
            
            # 获取最近的压力位作为目标价
            resistances = price_levels.get('resistance_levels', [])
            if len(resistances) > 0:
                target_price = resistances[0][1]
            else:
                target_price = current * 1.1  # 默认10%目标
            
            # 计算风险和收益
            risk = current - stop_loss
            reward = target_price - current
            
            if risk > 0:
                risk_reward_ratio = reward / risk
            else:
                risk_reward_ratio = 0
            
            # 评估
            if risk_reward_ratio >= 3:
                evaluation = '优秀（风险收益比≥3:1）'
            elif risk_reward_ratio >= 2:
                evaluation = '良好（风险收益比≥2:1）'
            elif risk_reward_ratio >= 1.5:
                evaluation = '一般（风险收益比≥1.5:1）'
            else:
                evaluation = '不佳（风险收益比<1.5:1）'
            
            return {
                'current_price': current,
                'target_price': round(target_price, 2),
                'stop_loss': round(stop_loss, 2),
                'potential_profit': round(reward, 2),
                'potential_loss': round(risk, 2),
                'profit_percent': round(reward / current * 100, 2),
                'loss_percent': round(risk / current * 100, 2),
                'risk_reward_ratio': round(risk_reward_ratio, 2),
                'evaluation': evaluation
            }
            
        except Exception as e:
            logging.error(f"计算风险收益比时出错: {e}")
            return {}

